//�������� 1:
// enum class
// initializer_list � ������������� ������ �������������
// auto
// decltype
// lambda 
// template variable


#include "stdafx.h"
#include "Header.h"
#include <iostream>

#define stop __asm nop
using namespace std;

int main()
{
	//������� 1. 
	{
		enum class months:unsigned char { January, February, March/*...*/ };
		enum class weekDays { Monday, Tuesday /*...*/ };

		months m = months::January;
		//�) ������� �������� (��� ������, ��� ���������� ��
		//������ ��������� ������������ ������������ �������
		//���������!)

		if (m == static_cast<months>(weekDays::Monday)) { /*...*/ }

		//�) ������������� ������������� ������
		
		months year[] = { months::January, months::February,months::March };
		size_t n = sizeof(year); //3

		stop
	}


	/**********************************************************/
		//������� 2. �������� � � ������� ������ �������������
		//��������� ���������� ������ � ���������� - string
		//� ������� range-based for ������������ ��� ����� � 	
		//������� ������� � ��������� ������� ������ ��������
		//�����������
	{
		vector<string> v_str {"zero=0", "one=1", "two=2", "three=3"};
		for (string& str : v_str)
		{
			std::transform(str.begin(), str.end(), str.begin(), toupper);
			/*for (char& symbol : str)
			{
				if (symbol >= 0x61 && symbol <= 0x7a)
					symbol -= 0x20;
			}*/
		}
		print_container(v_str);
		std::cout << std::endl;
		__asm nop
	}


	/**********************************************************/
		///������� 3. �������� � ��������� ����������
		//map ����� ��������� (3� � 3�) ����� �������, ����� �� �������� 
		//� �������� ����� �����, � � �������� �������� 
		//��������������� �� �������� ������������ ���� (string), 
		//������������ � ���� �����

		//3�. ������������������ map "�������" ����������� ������ �������������
		//� ������� range-based for � structured binding
		//������������ ����������, ��������: A: any, apple, away
	
	
	{
		map<char, set<string>> map_p{ {'A', { "any","away","apple" }}, { 'D',{"demon", "dark"}}};
		for (const auto& [f, s] : map_p)
		{
			cout << f << ": ";
			print_container(s);
		}
		std::cout << std::endl;
		__asm nop
	}

	//3�. �������� ������ map � ����������� �������� ������
	//��� ���������� �������.
	//� ������� range-based for � structured binding
	//������������ ����������, ��������: A: any, apple, away
	{

		
		//���� (��������):
		const char* s[] = { "yong", "away", "bar", "any", "son", "apple" };
		
		map<char, set<string>> map_p2;

		int n = sizeof(s) / sizeof(s[0]);

		for (int i = 0; i<n; i++)
		{
			char x = toupper(*s[i]);
			map_p2[x].insert(s[i]);
		}
		
		for (const auto& [f, s]	: map_p2)
		{
			cout << f << ": ";
			print_container(s);
		}
		std::cout << std::endl;
		__asm nop
	}


	/*********************************************************/
		//������� 4. ������� ������� ��� ������ �� ������
		//��������� �������������������, �������� ����:
	{
		std::vector<double> vd = { 1.1,2.2,3.3 };
		PrintAnyCont(vd);

		std::string s("abc");
		PrintAnyCont(s);

		int ar[] = { 1, 2, 3 };
		PrintAnyCont(ar);

		std::initializer_list<int> il{ 3,4,5 };
		PrintAnyCont(il);		
		std::cout << std::endl;
		__asm nop
	}


	/********************************************************/
		///������� 5. 	
		//C������ ������� ��� "���������" ��������, ��������:
		//����: {1, -2, 5}, �����: {-1, 2, -5})
		//��������� �������� ���� std::string ����� ��������� "aBc1" -> "AbC1"
		//��������� �������������������, �������� ����:
	{
		std::vector<double> vd{ 1.1,2.2,3.3 };
		NegateAll(vd);
		PrintAnyCont(vd);
		std::list<std::string> ls{ "aBc", "Qwerty", "n12" };
		NegateAll(ls);
		PrintAnyCont(ls);
		int ar[]{ 1, 2, 3 };
		NegateAll(ar);
		PrintAnyCont(ar);
		std::cout << std::endl;
		__asm nop
	}


	/********************************************************/
		//������� 6. ����������� ������� ���������� �� ������
		//��������� �������������������, �������� ����
		//���������� ��� ���������� ����� ������������ ����������
		//�������� sort(), � ��� ������� ������� - ������-�������
	{
		std::vector<double> vd = { -3.3,  2.2, -1.1 };
		absSort(vd);
		PrintAnyCont(vd);

		int ar[] = { -3, 2, -1 };
		absSort(ar);
		PrintAnyCont(ar);
		__asm nop
	}


	/********************************************************/
		//������� 7.
		//�������� �������, ������� ����� ����������� �
		//���������� ������, ������ ������� 
		//�������� �������� ������ ��������� ���� 
		//������������������� ������ �����
		//� � ���������� ������� ����.

		//��������� 1: ��� ��� ������������������ ����� ����
		//������ �����, ������� ������� ������ ���������������
		//������� ������������ �� ����

		//��������� 2: ��������� � ����������� �������������
		//���������� copy() � transform(), � ������� 
		//���������������� �������� ������ � ���� �������
		//�������� ������-��������

		//��������:
	{
		std::vector<int> v{ 1,2,3,4 };
		std::list<double> l{ 1.1, 2.2, 3.3, 4.4, 5.5 };

		auto Sum1 = SumCont(v, l);
		PrintAnyCont(Sum1);

		std::list<int> ll{ 1, 2, 3, 4, 5, 6, 7, 8 };
		double ar[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
		auto Sum2 = SumCont(ar, ll);
		PrintAnyCont(Sum2);

		std::set<std::string> s{ "abc", "qwerty", "my" };
		std::deque<const char*> d{ "111", "22" };
		auto Sum3 = SumCont(s, d);
		PrintAnyCont(Sum3);

		__asm nop
	}


	/********************************************************/
		//������� 8. ���������� �������, ������� ��������� ��������� ���������:	
		//�������������� ������������������ ������ ���� � ���������� ������ ����, 
		//��� (������) ���������� ������ ���� �� vector, list, deque, set 
		//� ���������� ���� �� ����, ��� � � �������������� ������������������ 

		//������� ������ "���������" �������� �������� ������������������ � ��� ������ ���������� 
		//�������� ��������� �������. ������� ������ �����-��������
		//�������� ������������������ ��� ���� �� ��������
	{
		//��������:
		std::vector<int> v{ 1,2,3,4,5 };
		std::list<int> l; //���� ������
		std::deque<int> d; //� ���� ��������
		Separate(v, l, d, [/*&*/](auto x) {return x & 1;});
		PrintAnyCont(v);
		PrintAnyCont(l);
		PrintAnyCont(d);
		__asm nop
	}


	/********************************************************/
		//������� 9. C ������� ��������� for_each()!!! 
		//(� �� count_if()) ��������� ������� ���� � �������
		//��������.
		//  ������������ ������ �������
	{
		char s[] = "HelLo WoRld!";
		//for_each 
		int count = 0;
		
		for_each(begin(s), end(s), [&count](auto& s) {if (isupper(s)) count++; });
		cout << count << endl;
		__asm nop
	}


	/********************************************************/
		//������� 10. ����������� ����������� enum � ��������� �������������  - enumToString
		// � �������� - stringToEnum

		//���������: 
		//***********
		//1. ��������������� ����������� ���������� ������ ��� ����� ����� ���-�� ������� =>
		// 
		// 
		//1.1 ����������� ��������� � ������������ ������ ���� ����������� => ��������������� ������
		//���� ������ ���� �����������, => ���������� ������ ����� ���� ������������ � ��������
		//����� � std::map

		//1.2 � ��� �������� (��������������� ���������� ����������)
		//����� ���� ������ � ���� ����� ����������� (�������� ������, ������, ��� �������� �� �����������) 
		//=> �������� ��������� std::map<string,<��������> >

		//1.3 �������� ��������� �++11 ���������� ������������� ���� ����� ���� ������� ������� � ����,
		//� �������� �� ���������� ������������� ����������� 

		//***********
		//2.1 ��� ��� ���� ������������ ������, �� enumToString � stringToEnum ������ ���� ����������
		//2.2 ������������ ����� ��������� ��� ������������ �������� � ������� ��������, �������
		//   ������ �� ������������� => ������!


		//***********
		//3. ����� �������� � map<string, <��������> > �� �������� �� ���� ������������, ��������� ��� ��������������
		//��������� ���������� (� ��������� ��������� � ����������� ������������� ��������� ����������)


		//***********

	{
		
		
		/*m1 = {{"RED",1}}; */
		//enum class COLORS { RED = 2, BLUE = 4, GREEN = 8 };
		

		//��������:
	
			COLORS c1 = COLORS::BLUE;
			auto m1 = Map<decltype(c1)>;
			try {
				c1 = stringToEnum<COLORS>("Blue");
			}
			catch (std::exception& x)
			{
				cout << x.what();
			}


		auto Str = enumToString(c1);
	

		__asm nop
	}

	return 0;
}
